// OrbitalCalculationWorker.js - 处理行星轨道计算的Web Worker

/**
 * 计算行星位置（基于简化的轨道模型）
 * @param {Object} planet - 行星数据
 * @param {number} time - 当前时间（以天为单位）
 * @returns {Object} 行星的位置和旋转状态 {position: {x,y,z}, rotation: number}
 */
function calculatePlanetPosition(planet, time) {
  // 计算轨道角度（基于时间和轨道周期）
  const orbitalAngle = (2 * Math.PI * time) / planet.orbitalPeriod;
  
  // 计算旋转角度（基于时间和自转周期）
  const rotationAngle = (2 * Math.PI * time) / planet.rotationPeriod;
  
  // 计算轨道位置
  const distance = planet.distance;
  const x = distance * Math.cos(orbitalAngle);
  const z = distance * Math.sin(orbitalAngle);
  
  // 根据真实比例进行缩放（如果需要）
  return {
    position: {
      x: x,
      y: 0, // 简化模型，行星位于XY平面
      z: z
    },
    rotation: rotationAngle
  };
}

/**
 * 计算所有行星及其卫星的位置
 * @param {Object} planetData - 所有行星数据
 * @param {number} time - 当前时间
 * @param {Object} options - 计算选项
 * @returns {Object} 所有天体的位置和旋转信息
 */
function calculateAllOrbitalPositions(planetData, time, options = {}) {
  const results = {};
  const { realScale = false, timeScale = 1.0 } = options;
  
  // 应用时间缩放
  const scaledTime = time * timeScale;
  
  // 计算每个行星的位置
  Object.entries(planetData).forEach(([planetName, planet]) => {
    const planetPos = calculatePlanetPosition(planet, scaledTime);
    
    results[planetName] = {
      position: planetPos.position,
      rotation: planetPos.rotation,
      satellites: {}
    };
    
    // 计算卫星的位置
    if (planet.satellites && planet.satellites.length > 0) {
      planet.satellites.forEach(satellite => {
        const satOrbitalAngle = (2 * Math.PI * scaledTime) / satellite.orbitalPeriod;
        const satRotationAngle = (2 * Math.PI * scaledTime) / satellite.rotationPeriod;
        
        // 卫星轨道半径
        const satelliteDistance = satellite.distance;
        
        // 卫星相对于行星的位置
        const relativeX = satelliteDistance * Math.cos(satOrbitalAngle);
        const relativeZ = satelliteDistance * Math.sin(satOrbitalAngle);
        
        // 卫星的绝对位置（相对于太阳）
        results[planetName].satellites[satellite.name] = {
          position: {
            x: planetPos.position.x + relativeX,
            y: planetPos.position.y,
            z: planetPos.position.z + relativeZ
          },
          rotation: satRotationAngle
        };
      });
    }
  });
  
  return results;
}

/**
 * 计算轨道点（用于绘制轨道）
 * @param {Object} planet - 行星数据
 * @param {number} numPoints - 轨道点数量
 * @returns {Array} 轨道点坐标数组
 */
function calculateOrbitPoints(planet, numPoints = 120) {
  const points = [];
  const distance = planet.distance;
  
  for (let i = 0; i < numPoints; i++) {
    const angle = (2 * Math.PI * i) / numPoints;
    
    points.push({
      x: distance * Math.cos(angle),
      y: 0,
      z: distance * Math.sin(angle)
    });
  }
  
  // 闭合轨道
  points.push(points[0]);
  
  return points;
}

/**
 * 计算所有行星的轨道点
 * @param {Object} planetData - 行星数据
 * @param {number} numPoints - 每个轨道的点数量
 * @returns {Object} 所有行星的轨道点
 */
function calculateAllOrbits(planetData, numPoints = 120) {
  const orbits = {};
  
  Object.entries(planetData).forEach(([planetName, planet]) => {
    orbits[planetName] = calculateOrbitPoints(planet, numPoints);
    
    // 如果有卫星，计算卫星轨道
    if (planet.satellites && planet.satellites.length > 0) {
      orbits[planetName].satellites = {};
      
      planet.satellites.forEach(satellite => {
        // 卫星轨道是相对于行星的
        const satelliteOrbit = calculateOrbitPoints(satellite, numPoints / 2); // 卫星轨道使用较少的点
        orbits[planetName].satellites[satellite.name] = satelliteOrbit;
      });
    }
  });
  
  return orbits;
}

/**
 * 将时间转换为轨道计算所需的天数
 * @param {number} seconds - 经过的秒数
 * @returns {number} 转换后的天数
 */
function secondsToDays(seconds) {
  return seconds / (24 * 60 * 60);
}

/**
 * 计算轨道速度向量
 * @param {Object} position - 当前位置
 * @param {number} orbitalPeriod - 轨道周期（天）
 * @returns {Object} 速度向量 {x,y,z}
 */
function calculateOrbitalVelocity(position, orbitalPeriod) {
  const r = Math.sqrt(position.x * position.x + position.z * position.z);
  const v = (2 * Math.PI * r) / orbitalPeriod;
  
  // 速度向量与位置向量垂直
  return {
    x: -v * position.z / r,
    y: 0,
    z: v * position.x / r
  };
}

/**
 * 计算轨道焦点（椭圆轨道的焦点）
 * @param {number} semiMajorAxis - 半长轴
 * @param {number} eccentricity - 偏心率
 * @returns {Object} 焦点位置 {x,y,z}
 */
function calculateOrbitalFocus(semiMajorAxis, eccentricity = 0) {
  const focusDistance = semiMajorAxis * eccentricity;
  return {
    x: focusDistance,
    y: 0,
    z: 0
  };
}

/**
 * 高级轨道计算（椭圆轨道）
 * @param {Object} orbitParams - 轨道参数
 * @param {number} time - 时间（天）
 * @returns {Object} 位置和速度
 */
function calculateEllipticalOrbit(orbitParams, time) {
  const { semiMajorAxis, eccentricity = 0, inclination = 0, ascendingNode = 0, argumentOfPeriapsis = 0, trueAnomaly = 0 } = orbitParams;
  
  // 简化计算：基于真近点角计算位置
  const nu = trueAnomaly + (2 * Math.PI * time) / 365.25; // 假设平均轨道周期为一年
  const r = (semiMajorAxis * (1 - eccentricity * eccentricity)) / (1 + eccentricity * Math.cos(nu));
  
  // 计算在轨道平面上的位置（极坐标转直角坐标）
  let x = r * Math.cos(nu + argumentOfPeriapsis);
  let y = r * Math.sin(nu + argumentOfPeriapsis);
  let z = 0;
  
  // 考虑轨道倾角
  const inclinationRad = (inclination * Math.PI) / 180;
  const tempX = x * Math.cos(inclinationRad) - y * Math.sin(inclinationRad);
  const tempY = x * Math.sin(inclinationRad) + y * Math.cos(inclinationRad);
  x = tempX;
  y = tempY;
  
  // 考虑升交点经度
  const nodeRad = (ascendingNode * Math.PI) / 180;
  const tempX2 = x * Math.cos(nodeRad) - z * Math.sin(nodeRad);
  const tempZ = x * Math.sin(nodeRad) + z * Math.cos(nodeRad);
  x = tempX2;
  z = tempZ;
  
  return {
    position: { x, y, z }
  };
}

/**
 * 计算行星和卫星之间的相对角度
 * @param {Object} planetPosition - 行星位置
 * @param {Object} satellitePosition - 卫星位置
 * @returns {number} 相对角度（弧度）
 */
function calculateRelativeAngle(planetPosition, satellitePosition) {
  const dx = satellitePosition.x - planetPosition.x;
  const dz = satellitePosition.z - planetPosition.z;
  return Math.atan2(dz, dx);
}

/**
 * 优化轨道计算，根据视距调整计算精度
 * @param {Object} planetData - 行星数据
 * @param {number} time - 时间
 * @param {Object} viewDistance - 视图距离
 * @returns {Object} 优化后的轨道数据
 */
function optimizedOrbitalCalculation(planetData, time, viewDistance) {
  // 根据距离动态调整精度
  const detailLevel = viewDistance > 5000 ? 0.5 : viewDistance > 2000 ? 0.7 : 1.0;
  const timeScale = 1.0 * detailLevel;
  const numOrbitPoints = Math.max(60, Math.floor(240 * detailLevel));
  
  // 应用不同的计算精度
  const results = {
    positions: calculateAllOrbitalPositions(planetData, time, { timeScale }),
    orbits: calculateAllOrbits(planetData, numOrbitPoints),
    detailLevel
  };
  
  return results;
}

// 监听主线程消息
self.onmessage = function(e) {
  const { action, data, options } = e.data;
  
  try {
    let result;
    
    switch (action) {
      case 'CALCULATE_PLANET_POSITION':
        result = calculatePlanetPosition(data.planet, data.time, options);
        break;
        
      case 'CALCULATE_ALL_POSITIONS':
        result = calculateAllOrbitalPositions(data.planetData, data.time, options);
        break;
        
      case 'CALCULATE_ORBIT_POINTS':
        result = calculateOrbitPoints(data.planet, options?.numPoints);
        break;
        
      case 'CALCULATE_ALL_ORBITS':
        result = calculateAllOrbits(data.planetData, options?.numPoints);
        break;
        
      case 'CALCULATE_ELLIPTICAL_ORBIT':
        result = calculateEllipticalOrbit(data.orbitParams, data.time);
        break;
        
      case 'OPTIMIZED_CALCULATION':
        result = optimizedOrbitalCalculation(data.planetData, data.time, data.viewDistance);
        break;
        
      default:
        throw new Error(`未知的操作: ${action}`);
    }
    
    // 发送结果回主线程
    self.postMessage({
      success: true,
      action: action,
      result: result
    });
  } catch (error) {
    // 发送错误信息回主线程
    self.postMessage({
      success: false,
      action: action,
      error: error.message
    });
  }
};

// 初始化完成通知
self.postMessage({
  success: true,
  action: 'INITIALIZED',
  result: 'OrbitalCalculationWorker 已初始化'
});